package com.llc.uh.quiz;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;

import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * This servlet responds to the posting of test answers.
 * It is called from quiz.jsp
 * 
 */
@SuppressWarnings("serial")
public class SendQuizDataServlet extends HttpServlet
{

    private static final Logger logger = Logger.getLogger(SendQuizDataServlet.class.getCanonicalName());
    private static String emailRecipient = "sfleming@hawaii.edu";
    
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {

        logger.log(Level.INFO, "Obtaining Item listing");

        // StringBuffer msgBody = new StringBuffer();
        // java.util.Formatter formatter = new java.util.Formatter(msgBody);
        String name;
        String value;
        Key key;
        String dsEmail;
        String formEmail = req.getParameter("email");
        System.out.println("first parameter email " + formEmail);
        Date date = new Date();

        String testanswer;
        String correctAnswer;
        String temp;
        String emailBody;
        Long keyId;
        float numQuestions = 20;
        float numCorrect = 0;
        float score = 0;
        Entity userOk = null;
        boolean duplicateEmail = false;

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

        /**
         * This is the list of form field "names" and "values". The names are
         * used to get the datastore key ID, e.g. (1,2,3...). With the key ID,
         * we can query the datastore for the correct answer.
         * 
         * The values are used to get the answer (a,b,c,d).
         * 
         * NOTE: unanswered questions are not in the following enumeration, this
         * means the number may vary, that's the way form submission works.
         * 
         * BUT: If using an HTML5 capable browser, it enforces that all
         * questions are answered.
         */
        Enumeration e = req.getParameterNames();

        Query query = new Query("User");
        List<Entity> users = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(100));

        /**
         * Handle email first. Get the email that was entered. Here we check
         * AGAIN in case the user pressed the back button and re-submitted the
         * page. if that's the case we give another redirect, no user entity
         * properties are stored, no email is sent.
         */
        for (Entity user : users)
        {
            dsEmail = (String) user.getProperty("email");

            if (dsEmail.equals(formEmail))
            {
                // A Re-Submit !
                duplicateEmail = true;
                System.err.println("XX: userEmail found in datastore" + " " + dsEmail);
            }
        }

        if (!duplicateEmail)
        {

            while (e.hasMoreElements())
            {
                // the name matches a quiz question key in the datastore
                name = (String) e.nextElement();

                // the email form parameter - we don't want to treat it like a question.
                if (name.equals("email"))
                {
                    /**
                     * We put the user's email from the form, in the user datastore. It cannot
                     * be allowed to be used again.
                     */

                    userOk = new Entity("User");
                    userOk.setProperty("email", formEmail);
                    userOk.setProperty("quizname", "Screening Exam for Chn399");
                    System.out.println("datetime " + date);

                    userOk.setProperty("dateTime", date);
                }

                else
                {
                    System.out.println("parameter name: " + name);
                    value = req.getParameter(name);
                    System.out.println("parameter value: " + value);

                    temp = name.substring(5, name.length() - 1);
                    System.out.println("keyId " + temp);
                    keyId = Long.valueOf(temp);

                    testanswer = value.substring(0, 1);
                    System.out.println("testanswer " + testanswer);

                    key = KeyFactory.createKey("Quiz", keyId);
                    query = new Query(key);
                    Entity question = datastore.prepare(query).asSingleEntity();
                    correctAnswer = (String) question.getProperty("correct");
                    System.out.println("correctanswer value: " + correctAnswer);

                    if (testanswer.equals(correctAnswer))
                    {
                        System.out.println("correctanswer");
                        numCorrect++;

                    }
                    else
                    {
                        System.out.println("INcorrectanswer");

                    }

                }

            } // while

            System.out.println("number correct " + numCorrect);
            score = (numCorrect / numQuestions) * 100;
            System.out.println("score " + score);

            userOk.setProperty("score", (int) score);
            userOk.setProperty("rawscore", (int) numCorrect);
            

            datastore.put(userOk);

            // send email with the following content:
            emailBody = formEmail + " got " + (int) numCorrect + " questions correct" + " for a score of " + (int) score + "%";
            System.out.println(emailBody);
            Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);

            try
            {

                Message msg = new MimeMessage(session);
                msg.setFrom(new InternetAddress("llc.manoa@gmail.com"));
                msg.addRecipient(Message.RecipientType.TO, new InternetAddress(emailRecipient));
                msg.setSubject(formEmail + " Submitted Screening Exam Answers for Chn399 Quiz");
                msg.setText(emailBody);
                Transport.send(msg);

            }
            catch (AddressException ae)
            {

                System.out.println(ae);

            }
            catch (MessagingException me)
            {

                System.out.println(me);
            }

        }

        resp.sendRedirect("/quizfinished.jsp");

    }// doPost
}
